package com.icetech.eom.controller.sys;


import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.icetech.commonbase.ResultTools;
import com.icetech.commonbase.constants.CodeConstantsEnum;
import com.icetech.commonbase.domain.response.ObjectResponse;
import com.icetech.eom.common.annotation.SystemLog;
import com.icetech.eom.common.constant.CommonConstant;
import com.icetech.eom.controller.vo.RoleVo;
import com.icetech.eom.domain.sys.*;
import com.icetech.eom.service.sys.*;
import com.icetech.eom.service.utils.SecurityUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author wangzwx
 */
@Slf4j
@RestController
@Api(description = "角色管理接口")
@RequestMapping("/role")
@Transactional(rollbackFor = RuntimeException.class)
public class RoleController {

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IRoleDepartmentService roleDepartmentService;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SecurityUtil securityUtil;
    @Autowired
    private IPermissionService permissionService;

    @RequestMapping(value = "/getAllList",method = RequestMethod.GET)
    @ApiOperation(value = "获取全部角色")
    @SystemLog(description = "获取全部角色列表")
    public ObjectResponse<Object> roleGetAll(){
        List<Role> list = roleService.getAllRole();
        return ResultTools.success(list);
    }

    @RequestMapping(value = "/listpage",method = RequestMethod.GET)
    @ApiOperation(value = "分页获取角色")
    @SystemLog(description = "分页获取全部角色列表")
    public ObjectResponse getRoleByPage(@RequestParam(value = "searchKey",defaultValue = "")String searchKey,
                                                    @RequestParam(value = "page",defaultValue = "1")Integer page,
                                                    @RequestParam(value = "pageSize",defaultValue = "20")Integer pageSize){

        PageInfo<Role> pageInfo = roleService.selectByPage(page,pageSize,searchKey);
        for(Role role : pageInfo.getList()){
            // 角色拥有权限
            List<RolePermission> permissions = rolePermissionService.findByRoleId(role.getId());
            role.setPermissions(permissions);
            // 角色拥有数据权限
            List<RoleDepartment> departments = roleDepartmentService.findByRoleId(role.getId());
            role.setDepartments(departments);
        }
        return ResultTools.getPageResponse(pageInfo.getList(),pageInfo.getTotal(),pageInfo.getPages());
    }

    @RequestMapping(value = "/setDefault",method = RequestMethod.POST)
    @ApiOperation(value = "设置或取消默认角色")
    @SystemLog(description = "设置或取消默认角色")
    public ObjectResponse setDefault(@RequestParam String id,
                                     @RequestParam Boolean isDefault){

        Role role = roleService.getById(id);
        if(role==null){
            return ResultTools.fail(CodeConstantsEnum.ERROR_404.getCode(),"角色不存在");
        }
        role.setDefaultRole(isDefault);
        roleService.updateById(role);
        return ResultTools.success(null);
    }

    @RequestMapping(value = "/editRolePerm",method = RequestMethod.POST)
    @ApiOperation(value = "编辑角色分配菜单权限")
    @SystemLog(description = "编辑角色分配菜单权限")
    public ObjectResponse editRolePerm(@RequestParam Long roleId,
                                       @RequestParam(required = false) Long[] permIds){

        //删除其关联权限
        rolePermissionService.deleteByRoleId(roleId);
        //分配新权限
        for(Long permId : permIds){
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permId);
            rolePermissionService.save(rolePermission);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ResultTools.success(null);
    }

    @RequestMapping(value = "/editRoleDep",method = RequestMethod.POST)
    @ApiOperation(value = "编辑角色分配数据权限")
    @SystemLog(description = "编辑角色分配数据权限")
    public ObjectResponse editRoleDep(@RequestParam Long roleId,
                                      @RequestParam Integer dataType,
                                      @RequestParam(required = false) Long[] depIds){

        Role r = roleService.getById(roleId);
        r.setDataType(dataType);
        roleService.updateById(r);
        // 删除其关联数据权限
        roleDepartmentService.deleteByRoleId(roleId);
        // 分配新数据权限
        for(Long depId : depIds){
            RoleDepartment roleDepartment = new RoleDepartment();
            roleDepartment.setRoleId(roleId);
            roleDepartment.setDepartmentId(depId);
            roleDepartmentService.save(roleDepartment);
        }

        // 手动删除相关缓存
        Set<String> keys = redisTemplate.keys("department:" + "*");
        redisTemplate.delete(keys);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);

        return ResultTools.success(null);
    }

    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "添加角色")
    @SystemLog(description = "添加角色")
    public ObjectResponse save(@RequestBody RoleVo roleVo){
        User currUser = securityUtil.getCurrUser();
        //创建角色
        Role role = new Role();
        BeanUtils.copyProperties(roleVo, role);
        roleService.save(role);
        //创建角色权限关联
        List<Long> permissionIds = roleVo.getPermissionIds();
        permissionIds.forEach(ID->{
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(ID);
            rolePermission.setRoleId(role.getId());
            rolePermission.setCreateBy(currUser.getUserName());
            rolePermissionService.save(rolePermission);
        });
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ResultTools.success(null);
    }

    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    @ApiOperation(value = "编辑角色")
    @SystemLog(description = "编辑角色")
    public ObjectResponse edit(@RequestBody RoleVo roleVo){
        Role role = roleService.getById(roleVo.getId());
        if (Objects.isNull(role)){
            return ResultTools.fail(CodeConstantsEnum.ERROR_400.getCode(),"当前角色不存在");
        }
        BeanUtils.copyProperties(roleVo, role);
        roleService.updateById(role);
        // 删除角色关联的权限
        rolePermissionService.deleteByRoleId(roleVo.getId());
        // 重新加载权限
        //分配新权限
        for(Long permId : roleVo.getPermissionIds()){
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleVo.getId());
            rolePermission.setPermissionId(permId);
            rolePermissionService.save(rolePermission);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ResultTools.success(null);
    }

    @RequestMapping(value = "/batchRemove",method = RequestMethod.GET)
    @ApiOperation(value = "批量通过ids删除")
    @SystemLog(description = "批量移除角色")
    public ObjectResponse batchRemove(@RequestParam("ids") List<Long> ids){

        for(Long id:ids){
            List<UserRole> list = userRoleService.findByRoleId(id);
            if(list!=null&&list.size()>0){
                return ResultTools.fail(CodeConstantsEnum.ERROR_402.getCode(),"删除失败，包含正被用户使用关联的角色");
            }
        }
        for(Long id:ids){
            roleService.removeById(id);
            //删除关联菜单权限
            rolePermissionService.deleteByRoleId(id);
            //删除关联数据权限
            roleDepartmentService.deleteByRoleId(id);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ResultTools.success(null);
    }
    @RequestMapping(value = "/remove",method = RequestMethod.GET)
    @ApiOperation(value = "通过id删除")
    @SystemLog(description = "删除角色")
    public ObjectResponse remove( Long id){

        List<UserRole> list = userRoleService.findByRoleId(id);
        if(list!=null&&list.size()>0){
            return ResultTools.fail(CodeConstantsEnum.ERROR_402.getCode(),"删除失败，包含正被用户使用关联的角色");
        }
        roleService.removeById(id);
        //删除关联菜单权限
        rolePermissionService.deleteByRoleId(id);
        //删除关联数据权限
        roleDepartmentService.deleteByRoleId(id);
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return ResultTools.success(null);
    }
    @RequestMapping(value = "/getChildrenByRoleId",method = RequestMethod.GET)
    @ApiOperation(value = "获取角色的子集菜单权限")
    @SystemLog(description = "删除角色")
    public ObjectResponse getChildrenByRoleId(@RequestParam("roleId") Long roleId){

        List<RolePermission> list = rolePermissionService.findByRoleId(roleId);
        List<Long> permissionIds = list.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
        //获取当前id中的子级菜单权限
        List<Permission> two = permissionService.findByIdsAndLevel(permissionIds, CommonConstant.LEVEL_TWO);
        List<Permission> three = permissionService.findByIdsAndLevel(permissionIds, CommonConstant.LEVEL_THREE);
        List<Permission> all = Lists.newArrayList();
        all.addAll(two);
        all.addAll(three);
        permissionIds = all.stream().map(Permission::getId).collect(Collectors.toList());
        return ResultTools.success(permissionIds);
    }
}
